Skip to content

test: list-item position fails to envelop fenced-code child#205

Open
ChristianMurphy wants to merge 1 commit intowooorm:mainfrom
ChristianMurphy:test/list-with-fenced-code-position
Open

test: list-item position fails to envelop fenced-code child#205
ChristianMurphy wants to merge 1 commit intowooorm:mainfrom
ChristianMurphy:test/list-with-fenced-code-position

Conversation

@ChristianMurphy
Copy link
Copy Markdown
Collaborator

to_mdast("- ```\n\nx\n", &ParseOptions::default()) returns Ok in 1.0.0 release but produces an mdast tree where the bullet list-item ends at offset 6 while its fenced-code child ends at offset 7, breaking the unist invariant that a parent's position envelops its child's. An analogous case fires for the ordered-list shape 1. ```\n\nx\n.

This is data-integrity, not a panic: to_mdast returns Ok, but downstream consumers indexing into source via child.position.end.offset will read past parent.position.end.offset. Affects language servers, source-mapped renderers, and any tool relying on positional invariants.

Adds a small assert_position_envelop helper that walks the mdast tree and reports parent/child position-mismatch violations. Reusable for future position-invariant regression tests.

Cause likely lives in src/construct/list_item.rs: the list-item event pair closes on the blank-line offset before the fenced-code construct finishes capturing content, so on_exit_list_item finalizes the position before the code child gets its broader span. Cheapest fix: post-process parent positions in on_exit_list_item to envelop child spans.

Verified to fail against markdown = "=1.0.0" in release. Found via in-tree fuzzing campaign.

`to_mdast("- ```\n\nx\n", &ParseOptions::default())` returns Ok in 1.0.0
release but produces an mdast tree where the bullet list-item ends at
offset 6 while its fenced-code child ends at offset 7 — breaking the
unist invariant that a parent's position envelops its child's. An
analogous case fires for the ordered-list shape `1. ```\n\nx\n`.

This is data-integrity, not a panic: `to_mdast` returns `Ok`, but
downstream consumers indexing into source via `child.position.end.offset`
will read past `parent.position.end.offset`. Affects language servers,
source-mapped renderers, and any tool relying on positional invariants.

Adds a small `assert_position_envelop` helper that walks the mdast tree
and reports parent/child position-mismatch violations. Reusable for
future position-invariant regression tests.

Cause likely lives in `src/construct/list_item.rs`: the list-item event
pair closes on the blank-line offset before the fenced-code construct
finishes capturing content, so `on_exit_list_item` finalizes the
position before the code child gets its broader span. Cheapest fix:
post-process parent positions in `on_exit_list_item` to envelop child
spans.

Verified to fail against `markdown = "=1.0.0"` in release. Found via
in-tree fuzzing campaign.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant